from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import List, Dict, Any, Optional
import json
from datetime import datetime

from database import get_db, DecisionRule, DataSource, DataRecord
from services.ai_service import ai_service
from services.cache_service import CacheService, CacheKeys

router = APIRouter()

class DecisionRuleCreate(BaseModel):
    name: str
    description: str
    prompt_template: str
    data_sources: List[str]

class DecisionRuleUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    prompt_template: Optional[str] = None
    data_sources: Optional[List[str]] = None
    is_active: Optional[bool] = None

class DecisionRequest(BaseModel):
    question: str
    rule_id: Optional[int] = None
    context_data: Optional[Dict[str, Any]] = None

@router.get("/rules")
async def get_decision_rules(db: Session = Depends(get_db)):
    """获取所有决策规则"""
    try:
        rules = db.query(DecisionRule).all()
        
        result = []
        for rule in rules:
            try:
                data_sources = json.loads(rule.data_sources) if rule.data_sources else []
            except json.JSONDecodeError:
                data_sources = []
            
            result.append({
                "id": rule.id,
                "name": rule.name,
                "description": rule.description,
                "prompt_template": rule.prompt_template,
                "data_sources": data_sources,
                "is_active": rule.is_active,
                "created_at": rule.created_at.isoformat()
            })
        
        return {
            "success": True,
            "rules": result,
            "total": len(result)
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取决策规则失败: {str(e)}")

@router.post("/rules")
async def create_decision_rule(
    rule: DecisionRuleCreate,
    db: Session = Depends(get_db)
):
    """创建决策规则"""
    try:
        # 检查名称是否已存在
        existing = db.query(DecisionRule).filter(DecisionRule.name == rule.name).first()
        if existing:
            raise HTTPException(status_code=400, detail="决策规则名称已存在")
        
        # 创建新规则
        new_rule = DecisionRule(
            name=rule.name,
            description=rule.description,
            prompt_template=rule.prompt_template,
            data_sources=json.dumps(rule.data_sources, ensure_ascii=False)
        )
        
        db.add(new_rule)
        db.commit()
        db.refresh(new_rule)
        
        return {
            "success": True,
            "rule": {
                "id": new_rule.id,
                "name": new_rule.name,
                "description": new_rule.description,
                "prompt_template": new_rule.prompt_template,
                "data_sources": rule.data_sources,
                "is_active": new_rule.is_active,
                "created_at": new_rule.created_at.isoformat()
            }
        }
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"创建决策规则失败: {str(e)}")

@router.put("/rules/{rule_id}")
async def update_decision_rule(
    rule_id: int,
    rule: DecisionRuleUpdate,
    db: Session = Depends(get_db)
):
    """更新决策规则"""
    try:
        existing_rule = db.query(DecisionRule).filter(DecisionRule.id == rule_id).first()
        if not existing_rule:
            raise HTTPException(status_code=404, detail="决策规则不存在")
        
        # 更新字段
        update_data = rule.dict(exclude_unset=True)
        for field, value in update_data.items():
            if field == "data_sources" and value is not None:
                value = json.dumps(value, ensure_ascii=False)
            setattr(existing_rule, field, value)
        
        db.commit()
        db.refresh(existing_rule)
        
        # 清除缓存
        cache_key = CacheKeys.decision_rule_key(rule_id)
        await CacheService.delete(cache_key)
        
        try:
            data_sources = json.loads(existing_rule.data_sources) if existing_rule.data_sources else []
        except json.JSONDecodeError:
            data_sources = []
        
        return {
            "success": True,
            "rule": {
                "id": existing_rule.id,
                "name": existing_rule.name,
                "description": existing_rule.description,
                "prompt_template": existing_rule.prompt_template,
                "data_sources": data_sources,
                "is_active": existing_rule.is_active
            }
        }
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新决策规则失败: {str(e)}")

@router.delete("/rules/{rule_id}")
async def delete_decision_rule(rule_id: int, db: Session = Depends(get_db)):
    """删除决策规则"""
    try:
        rule = db.query(DecisionRule).filter(DecisionRule.id == rule_id).first()
        if not rule:
            raise HTTPException(status_code=404, detail="决策规则不存在")
        
        db.delete(rule)
        db.commit()
        
        # 清除缓存
        cache_key = CacheKeys.decision_rule_key(rule_id)
        await CacheService.delete(cache_key)
        
        return {
            "success": True,
            "message": f"决策规则 '{rule.name}' 已删除"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除决策规则失败: {str(e)}")

@router.post("/analyze")
async def analyze_decision(
    request: DecisionRequest,
    db: Session = Depends(get_db)
):
    """分析决策请求"""
    try:
        # 获取决策规则（如果指定）
        decision_rule = None
        if request.rule_id:
            decision_rule = db.query(DecisionRule).filter(
                DecisionRule.id == request.rule_id,
                DecisionRule.is_active == True
            ).first()
            
            if not decision_rule:
                raise HTTPException(status_code=404, detail="决策规则不存在")
        
        # 获取上下文数据
        context_data = request.context_data or {}
        
        if not context_data and decision_rule:
            # 从决策规则指定的数据源获取数据
            try:
                data_sources = json.loads(decision_rule.data_sources)
                for source_type in data_sources:
                    source = db.query(DataSource).filter(
                        DataSource.data_type == source_type,
                        DataSource.is_active == True
                    ).first()
                    
                    if source:
                        latest_record = db.query(DataRecord).filter(
                            DataRecord.source_id == source.id
                        ).order_by(DataRecord.timestamp.desc()).first()
                        
                        if latest_record:
                            try:
                                data = json.loads(latest_record.data_json)
                                context_data[source_type] = {
                                    "data": data,
                                    "last_updated": latest_record.timestamp.isoformat(),
                                    "source_name": source.name
                                }
                            except json.JSONDecodeError:
                                continue
            except json.JSONDecodeError:
                pass
        
        # 使用AI服务分析
        analysis_result = await ai_service.get_decision_advice(
            user_question=request.question,
            context_data=context_data,
            decision_rule=decision_rule.prompt_template if decision_rule else None
        )
        
        return {
            "success": True,
            "analysis": analysis_result,
            "rule_used": {
                "id": decision_rule.id,
                "name": decision_rule.name
            } if decision_rule else None,
            "data_sources_used": list(context_data.keys()),
            "timestamp": datetime.now().isoformat()
        }
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"分析决策失败: {str(e)}")

@router.get("/templates")
async def get_decision_templates():
    """获取决策模板"""
    return {
        "success": True,
        "templates": [
            {
                "id": "travel_planning",
                "name": "旅行规划决策",
                "description": "基于天气、疫情、交通等数据制定旅行计划",
                "prompt_template": """你是一个旅行规划专家。请基于提供的数据为用户制定旅行建议。

考虑因素：
1. 天气条件对旅行的影响
2. 疫情风险和安全措施
3. 交通状况和路线选择
4. 目的地的最佳访问时间

请提供：
- 是否适合旅行的建议
- 具体的安全措施
- 推荐的行程安排
- 需要携带的物品清单""",
                "data_sources": ["weather", "covid", "traffic"]
            },
            {
                "id": "health_decision",
                "name": "健康决策",
                "description": "基于疫情、流感等数据做出健康相关决策",
                "prompt_template": """你是一个健康顾问。请基于提供的数据为用户提供健康建议。

考虑因素：
1. 当前疫情传播情况
2. 流感活跃度
3. 空气质量状况
4. 个人防护措施

请提供：
- 健康风险评估
- 防护建议
- 是否需要就医
- 预防措施""",
                "data_sources": ["covid", "flu", "air_quality"]
            },
            {
                "id": "investment_decision",
                "name": "投资决策",
                "description": "基于经济数据做出投资相关决策",
                "prompt_template": """你是一个投资顾问。请基于提供的数据为用户提供投资建议。

考虑因素：
1. 宏观经济指标
2. 市场趋势分析
3. 风险评估
4. 投资时机

请提供：
- 市场分析
- 投资建议
- 风险提示
- 投资组合建议""",
                "data_sources": ["economic"]
            }
        ]
    }
